package safe_lru

import (
	"sync"

	"bulgat.top/go_cache/cache"
	"bulgat.top/go_cache/unsafe_lru"
)

type Cache struct {
	lock  sync.RWMutex
	cache *unsafe_lru.Cache
}

func New(capacity int64, deletedCallBack func(key string, value cache.Value)) *Cache {
	return &Cache{
		lock:  sync.RWMutex{},
		cache: unsafe_lru.New(capacity, deletedCallBack),
	}
}

func (c *Cache) Get(key string) (value cache.Value, exists bool) {
	c.lock.RLock()
	defer c.lock.RUnlock()
	v, exists := c.cache.Get(key)
	if !exists {
		return nil, false
	}
	if bv, ok := v.(ByteView); ok {
		return bv.Clone(), true
	}
	return v, true
}

func (c *Cache) Put(key string, value cache.Value) (err error) {
	c.lock.Lock()
	defer c.lock.Unlock()
	return c.cache.Put(key, value)
}

func (c *Cache) Delete(key string) (value cache.Value) {
	c.lock.Lock()
	defer c.lock.Unlock()
	return c.cache.Delete(key)
}

func (c *Cache) Capacity() int64 {
	return c.cache.Capacity()
}

func (c *Cache) Size() int64 {
	return c.cache.Size()
}

func (c *Cache) KeysLen() int64 {
	return c.cache.KeysLen()
}
